package pl.enigmatic.validation.fields;

import pl.enigmatic.validation.HasValue;
import pl.enigmatic.validation.ValidatingForm;


public abstract class FieldsValidatingForm<T, W extends HasValue<?>, P, F extends Enum<F> & Field<T, Object>, E extends Enum<E> & Error<F>, Editor extends HasFieldWidgets<F, W>>
		extends ValidatingForm<W, P> {

	private final Class<F> fields;
	private final Class<E> errors;
	private final Editor editor;

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public FieldsValidatingForm(final Class<F> fields, final Class<E> errors, final Editor editor) {
		this.fields = fields;
		this.errors = errors;
		this.editor = editor;
		for (final E err : errors.getEnumConstants()) {
			final F field = err.getField();
			if (editor.contains(field)) {
				addValidation(field.name(), err.name(), (HasValue) editor.getEditor(field), err.getValidator());
			}
		}
	}

	public Class<F> getFields() {
		return fields;
	}

	public Class<E> getErrors() {
		return errors;
	}

	protected abstract String getErrorMessage(final E error);

	@Override
	protected final String getErrorMessage(final String code) {
		return getErrorMessage(Enum.valueOf(errors, code));
	}

	public Editor getEditor() {
		return editor;
	}
}
